package com.naja.auth2server.common;

import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

/**
 * @auther jw
 * @date 2022-01-21
 */
@Slf4j
public class MyClassLoader extends ClassLoader{

    private final String fileSuffix = ".class";
    private String classLocation;

    public MyClassLoader(String classLocation) {
        super();
        this.classLocation = classLocation;
    }

    public MyClassLoader(ClassLoader parentClassLoader, String classLocation) {
        super(parentClassLoader);
        this.classLocation = classLocation;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classData = loadClassData(name);
        return defineClass(name, classData, 0, classData.length);
    }

    private byte[] loadClassData(String name) {
        byte[] data = null;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             InputStream is = new FileInputStream(new File(classLocation + name.replace(".", "/") + fileSuffix));){
            int r = 0;
            while (-1 != (r = is.read())) {
                baos.write(r);
            }
            is.close();
            baos.close();
            data = baos.toByteArray();
        } catch (Exception ex) {
            log.error("加载class异常", ex);
        }
        return data;
    }

    @Override
    public String toString() {
        return "This is MyClassLoader:" + this.getClass().getSimpleName();
    }

    public static void main(String[] args) throws Exception {
        //jdk禁止自定义加载java开头的包
        MyClassLoader myCl = new MyClassLoader(ClassLoader.getSystemClassLoader(), "/Users/jw/IdeaProjects/vr-cyberspace-manage/src/main/java/");
        testClassLoader(myCl);
    }

    private static void testClassLoader(MyClassLoader cl) throws Exception {
        Class<?> clazz = cl.findClass("java.lang.String");
        System.out.println(clazz.getClassLoader().toString());

        Object newObj = clazz.newInstance();
        System.out.println(newObj.toString());
    }
}
